"""
通过线程池/进程池分配线程/进程执行任务
    ~ submit(函数, 参数) - 分配一个线程执行一个任务
    ~ map(函数, 多个任务对应的参数) - 一次性分派多个任务
进程间通信（IPC）：
    ~ 管道（pipe） - 操作系统底层的I/O通道 - multiprocessing.queue
    ~ 套接字（socket）- 基于网络服务构建I/O通道
I/O模式：
    ~ 阻塞式I/O - 同步阻塞
    ~ 非阻塞式I/O - 同步非阻塞
    ~ 多路I/O复用 - 同步非阻塞 - select - 事件循环 + 轮询（Windows、macOS）
    ~ 信号驱动I/O（上面的改进版）- epoll（Linux） / kqueue（BSD） - 事件循环 + 通知
    ~ 异步I/O（非阻塞回调式I/O）- asyncio / async / await - 异步非阻塞 - iocp（新Windows）
事件循环 - 最好的事件循环是uvloop - libuv
多个相互协作的子程序，某个子程序一旦因为I/O操作阻塞就主动让出CPU，让与之协作的子程序
可以接续它执行，这些相互协作的子程序就称之为协程，通过协程可以实现协议式的并发
协程是一个线程下相互协作的多个子程序，所以有人也称之为微线程或纤程 - coroutine
    ~ yield - 让步 / 产出
问题：什么是同步？什么是异步？
"""
import concurrent.futures
import math

PRIMES = [
    1116281,
    1297337,
    104395303,
    472882027,
    533000389,
    817504243,
    982451653,
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419
] * 5


def is_prime(n):
    """判断素数"""
    if n == 2:
        return True

    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True


def main():
    """主函数"""
    with concurrent.futures.ProcessPoolExecutor(max_workers=16) as pool:
        for number, prime in zip(PRIMES, pool.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))


if __name__ == '__main__':
    main()
